package forumcorba;

import java.util.concurrent.ConcurrentHashMap;

import org.omg.CORBA.IntHolder;
import org.omg.CORBA.StringHolder;

import forumcorba.tpforum.ForumPOA;
import forumcorba.tpforum.Message;
import forumcorba.tpforum.Reject;



/**
 * Applications reparties
 * TP
 * Forum simple en CORBA
 * 
 * Classe representant un forum
 * (classe de futurs objets serveurs (servants))
 * 
 * @author Toto
 * @version 1.0
 */
public class ForumImpl extends ForumPOA {

	/**
	 * Table de hachage contenant les associations entre un nom et un message.
	 * L'acces concurrent a la table est permis.
	 */
	private ConcurrentHashMap<String, Message> messages;

	/** 
	 * Theme du forum 
	 */
	private String theme;

	/** 
	 * Nom de l'administrateur
	 */
	private String moderator;


	/**
	 * Constructeur par defaut d'un forum.
	 */
	ForumImpl() {
		this.theme = "CORBA";
		this.moderator = "Toto";
		this.messages = new ConcurrentHashMap<String, Message>();
	}

	
	/**
	 * Constructeur d'un forum appele par la fabrique.
	 * @param name nom du forum cree.
	 * @param theme theme du forum.
	 * @param moderator nom de l'administrateur du forum.
	 */
	ForumImpl(String theme, String moderator) {
		this.theme = theme;
		this.moderator = moderator;
		this.messages = new ConcurrentHashMap<String, Message>();
	}

	
	/**
	 * Retourne le theme du forum.
	 * @return String Le theme
	 */
	public String theme() {
		return this.theme;
	}

	
	/**
	 * Retourne le nom du moderateur du forum.
	 * @return String Le moderateur 
	 */
	public String moderator() {
		return this.moderator;
	}

	
	/**
	 * Poste un message dans le forum.
	 * @param m le message a poster.
	 * @return true si tout est ok.
	 * @throws Reject Si un message avec le meme titre existe deja.
	 */
	public boolean postMessage(Message m) throws Reject {
		Message mInMap = messages.putIfAbsent(m.title ,m);
		if(mInMap != null) {
			throw new Reject("PostMessage : message with title \""+m.title + "\" already exists!");
		}
		return true;
	}
	
	
	/**
	 * Recupere le message dont le titre est passe en argument.
	 * @param title le titre du message a recuperer.
	 * @return le message ayant ce titre.
	 * @throws Reject Si aucun message avec ce titre existe.
	 */
	public Message getMessage(String title) throws Reject {
		Message m = messages.get(title);
		if(m == null) {
			throw new Reject("GetMessage : message with title \""+ title+"\" does not exist!");
		}
		return m;
	}
	
	
	/**
	 * Supprime un message du forum.
	 * @param title le titre du message a retirer du forum.
	 * @return true si tout est ok.
	 * @throws Reject Si le message n'est pas present dans le forum.
	 */
	public boolean removeMessage(String title) throws Reject {
		if(messages.remove(title) == null) {
			throw new Reject ("RemoveMessage : message \"" + title +"\" does not exist!");
		}
		return true;
	}


	/**
	 * Retourne la liste des messages du forum.
	 * @return Un tableau de messages
	 */
	public Message[] getMessages() {
		return messages.values().toArray(new Message[messages.size()]);
	}


	/**
	 * Retourne dans les arguments les informations sur le forum.
	 * @param theme Theme du forum
	 * @param moderator Moderateur du forum
	 * @param size Nombre de messages dans le forum
	 */
	public void getInfo(StringHolder theme, StringHolder moderator,	IntHolder size) {
		theme.value = this.theme;
		moderator.value = this.moderator;
		size.value = messages.size();
	}

	
}

